<template>
	<component
		:is="component"
		v-model="fileList"
		:max="max"
		:plus="plus"
		:accept="accept"
		:disabled="disabled"
		@on-success="result => $emit('on-success', result)"
		@on-remove="options => $emit('on-remove', options)"
	>
	</component>
</template>

<script setup>
import vImage from "./components/image.vue"
import vVideo from "./components/video.vue"
import vFile from "./components/file.vue"

const props = defineProps({
	max: {
		type: [Number, String],
		default: -1,
	},
	disabled: {
		type: Boolean,
		default: false,
	},
	modelValue: {
		type: [Array, String],
		default: "",
	},
	type: {
		type: String,
		default: "image",
	},
	spacer: {
		type: [String, Boolean],
		default: ",",
	},
	join: {
		type: [String, Boolean],
	},
	json: {
		type: Boolean,
	},
	plus: {
		type: Boolean,
		default: true,
	},
})

const emits = defineEmits(["update:modelValue", "on-success", "on-remove"])

const component = computed(() => {
	const components = {
		image: vImage,
		video: vVideo,
	}
	return components[props.type] || vFile
})

const spacer = computed(() => {
	if (typeof props.spacer === "string") return props.spacer
	if (typeof props.join === "string") return props.join
	return ","
})
const join = computed(() => {
	if (typeof props.join === "string") return props.join
	if (typeof props.spacer === "string") return props.spacer
	return ","
})

const fileList = computed({
	get() {
		if (props.modelValue === "" || props.modelValue === undefined || props.modelValue === null) return []
		if (Array.isArray(props.modelValue)) {
			return props.modelValue.map(item => {
				if (typeof item === "string")
					return {
						url: item,
						name: item.split("/").pop() || "",
					}
				return item
			})
		}
		if (typeof props.modelValue === "string") {
			if (props.json) {
				return JSON.parse(props.modelValue)
			}
			if (props.spacer || props.join) {
				return props.modelValue.split(spacer.value).map(item => ({
					url: item,
					name: item.split("/").pop() || "",
				}))
			}
		}
		return []
	},
	set(value) {
		if (props.join || props.spacer) {
			emits("update:modelValue", value.map(item => item.url).join(join.value))
		} else if (props.json) {
			emits("update:modelValue", JSON.stringify(value))
		} else {
			emits("update:modelValue", value)
		}
	},
})
const accept = computed(() => {
	if (props.type === "image") {
		return "image/*"
	} else if (props.type === "video") {
		return "video/*"
	}
	return "*"
})
</script>

<style lang="scss" scoped></style>
